package org.sixtynine.stock.controller;

import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;

import org.sixtynine.stock.ReturnData;
import org.sixtynine.stock.dto.GridPramDTO;
import org.sixtynine.stock.dto.Page;
import org.sixtynine.stock.entity.AspiData;
import org.sixtynine.stock.entity.BaseEntity;
import org.sixtynine.stock.entity.Sector;
import org.sixtynine.stock.entity.User;
import org.sixtynine.stock.model.FileUploadForm;
import org.sixtynine.stock.model.LoadingSearchCriteria;
import org.sixtynine.stock.service.AspiDataService;
import org.sixtynine.stock.service.GenericService;
import org.sixtynine.stock.service.content.DataManagerService;
import org.sixtynine.stock.service.file.ExcelProcessorFactory;
import org.sixtynine.stock.service.file.FileDataService;
import org.sixtynine.stock.util.SessionBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

/**
 * @author Thilan this class handle daily sector data
 */

@Controller
@SessionAttributes
public class MonthlyAspiController extends BackEndAuthController {

	private int RECORDS_PER_PAGE = 10;

	@Autowired
	private GenericService genericService;

	@Autowired
	private FileDataService fileDataService;

	@Autowired
	DataManagerService dataManagerService;

	@Autowired
	private AspiDataService monthlyAspiDataService;

	@RequestMapping(value = "/admin/monthlyaspi/search")
	public ModelAndView search(@ModelAttribute LoadingSearchCriteria criteria) {
		ModelAndView modelAndView = new ModelAndView("/admin/monthlyaspi/list");
		loadData(1, -1, criteria.getFromDate(), criteria.getToDate(),
				modelAndView, criteria);

		return modelAndView;
	}

	@RequestMapping(value = "/admin/monthlyaspi/add")
	public ModelAndView addMonthlySectorData(HttpServletRequest request) {
		ModelAndView modelAndView = null;

		if (!isUserLogged(request)) {
			modelAndView = new ModelAndView("/login/login");
			return modelAndView;
		}
		modelAndView = new ModelAndView("/admin/monthlyaspi/add");
		modelAndView.addObject("monthlyAspiData", new AspiData());
		modelAndView.addObject("userLogged", true);

		return modelAndView;
	}

	@RequestMapping(value = "/admin/monthlyaspi/add/sector_process")
	public ModelAndView addingSectorsByFile(
			@ModelAttribute("uploadFile") FileUploadForm uploadFile) {
		ModelAndView modelAndView = new ModelAndView("/admin/monthlyaspi/add");
		modelAndView.addObject("monthlyAspiData", new AspiData());

		MultipartFile multipartFile = uploadFile.getFile();
		ReturnData<String> fileSaveReturnData = fileDataService.saveFile(
				multipartFile,
				ExcelProcessorFactory.FILE_TYPE_MONTHLY_ASPI_DATA_LIST, null);

		StringBuilder message = new StringBuilder();
		if (fileSaveReturnData._isSuccess()) {
			// if success, process it
			ReturnData<List<? extends BaseEntity>> returnData = fileDataService
					.process(
							multipartFile.getOriginalFilename(),
							ExcelProcessorFactory.FILE_TYPE_MONTHLY_ASPI_DATA_LIST);
			if (returnData._isSuccess()) {
				message.append("file " + multipartFile.getOriginalFilename()
						+ " uploaded and inserted successfully");
				modelAndView = new ModelAndView("/admin/monthlyaspi/list");
				modelAndView.addObject("message", message);
				loadData(1, -1, null, null, modelAndView, null);
			} else {
				message.append(returnData.getMsg());
			}
		} else {
			message.append(fileSaveReturnData.getMsg());
		}

		return modelAndView;
	}

	@RequestMapping(value = "/admin/monthlyaspi/add/process")
	public ModelAndView addingMonthlySectorData(
			@ModelAttribute @Valid AspiData monthlyAspiData,
			BindingResult result) {
		ModelAndView modelAndView = null;
		if (!result.hasErrors()) {
			genericService.saveOrUpdate(monthlyAspiData);
			modelAndView = new ModelAndView("/admin/monthlyaspi/list");
			loadData(1, -1, monthlyAspiData.getDate(),
					monthlyAspiData.getDate(), modelAndView, null);
		} else {
			modelAndView = new ModelAndView("/admin/monthlyaspi/add");
			List<BaseEntity> sectors = genericService.findAll(Sector.class);
			modelAndView.addObject("sectorsMap", sectors);
		}
		return modelAndView;
	}

	@RequestMapping(value = "/admin/monthlyaspi/list")
	public ModelAndView listOfMonthlySectorData(
			HttpServletRequest request,
			@RequestParam(value = "page", required = false) Integer page,
			@RequestParam(value = "totalRecords", required = false) Integer totalRecords) {
		ModelAndView modelAndView = null;

		if (!isUserLogged(request)) {
			modelAndView = new ModelAndView("/login/login");
			return modelAndView;
		}
		modelAndView = new ModelAndView("/admin/monthlyaspi/list");
		loadData(page, totalRecords, null, null, modelAndView, null);
		modelAndView.addObject("userLogged", true);
		return modelAndView;
	}

	/**
	 * load data
	 * 
	 * @param page
	 * @param totalRecords
	 * @param companyId
	 * @param fromDate
	 * @param toDate
	 * @param modelAndView
	 */
	private void loadData(Integer page, Integer totalRecords, Date fromDate,
			Date toDate, ModelAndView modelAndView,
			LoadingSearchCriteria criteria) {
		GridPramDTO gridPramDTO = new GridPramDTO();
		gridPramDTO.setRows(RECORDS_PER_PAGE);
		if (page != null) {
			gridPramDTO.setPage(page);
		} else {
			gridPramDTO.setPage(1);
		}
		if (totalRecords != null) {
			gridPramDTO._setTotalNumberOfRecords(totalRecords);
		}

		Page<AspiData> monthlyAspiDataPage = monthlyAspiDataService
				.searchMonthlyAspiData(fromDate, toDate, "date", gridPramDTO);
		modelAndView.addObject("monthlyAspiDataPage", monthlyAspiDataPage);

		List<BaseEntity> sectors = genericService.findAll(Sector.class);
		modelAndView.addObject("sectorsMap", sectors);
		if (criteria == null) {
			criteria = new LoadingSearchCriteria();
			criteria.setFromDate(fromDate);
			criteria.setToDate(toDate);
		}
		modelAndView.addObject("criteria", criteria);

	}

	@RequestMapping(value = "/admin/monthlyaspi/edit/{id}", method = RequestMethod.GET)
	public ModelAndView editMonthlySectorData(HttpServletRequest request,
			@PathVariable Integer id) {
		ModelAndView modelAndView = null;

		if (!isUserLogged(request)) {
			modelAndView = new ModelAndView("/login/login");
			return modelAndView;
		}
		modelAndView = new ModelAndView("/admin/monthlyaspi/edit");
		BaseEntity monthlyAspiData = genericService
				.findById(id, AspiData.class);
		modelAndView.addObject("monthlyAspiData", monthlyAspiData);
		modelAndView.addObject("userLogged", true);

		return modelAndView;
	}

	@RequestMapping(value = "/admin/monthlyaspi/edit/{id}", method = RequestMethod.POST)
	public ModelAndView edditingMonthlySectorData(
			@ModelAttribute @Valid AspiData monthlyAspiData,
			BindingResult result, @PathVariable Integer id) {
		ModelAndView modelAndView = null;
		if (!result.hasErrors()) {
			genericService.saveOrUpdate(monthlyAspiData);
			modelAndView = new ModelAndView("/admin/monthlyaspi/list");
			String message = "Record was successfully edited.";
			modelAndView.addObject("message", message);
			loadData(1, -1, monthlyAspiData.getDate(),
					monthlyAspiData.getDate(), modelAndView, null);

			return modelAndView;
		} else {
			modelAndView = new ModelAndView("/admin/monthlyaspi/edit");
		}

		return modelAndView;
	}

	@RequestMapping(value = "/admin/monthlyaspi/delete/{id}", method = RequestMethod.GET)
	public ModelAndView deleteMonthlySectorData(@PathVariable Integer id,
			HttpServletRequest request) {
		ModelAndView modelAndView = null;

		if (!isUserLogged(request)) {
			modelAndView = new ModelAndView("/login/login");
			modelAndView.addObject("registedUser", new User());
			return modelAndView;
		}

		genericService.delete(id, AspiData.class);
		modelAndView = new ModelAndView("/admin/monthlyaspi/list");
		String message = "Record was successfully deleted.";
		modelAndView.addObject("message", message);
		loadData(1, -1, null, null, modelAndView, null);
		return modelAndView;
	}

	@RequestMapping(value = "/admin/monthlyaspi/delete/selected")
	public ModelAndView deleteSelectedDailySectorData(
			HttpServletRequest request,
			@RequestParam(value = "deleteIds", required = false) Integer[] deleteIds) {

		ModelAndView modelAndView = null;

		if (!isUserLogged(request)) {
			modelAndView = new ModelAndView("/login/login");
			modelAndView.addObject("registedUser", new User());
			return modelAndView;
		}

		if (deleteIds != null) {
			for (Integer deleteId : deleteIds) {
				genericService.delete(deleteId, AspiData.class);
			}
		}

		modelAndView = new ModelAndView("/admin/monthlyaspi/list");
		// set the criteria
		modelAndView.addObject("criteria", new LoadingSearchCriteria());
		String message = "Selected Records deleted successfully.";
		modelAndView.addObject("message", message);

		loadData(1, -1, null, null, modelAndView, null);
		return modelAndView;
	}

	@RequestMapping(value = "/admin/monthlyaspi/deleteFiltered")
	public ModelAndView deleteFilteredDailySectorData(
			@ModelAttribute LoadingSearchCriteria criteria,
			HttpServletRequest request) {
		ModelAndView modelAndView = null;

		if (!isUserLogged(request)) {
			modelAndView = new ModelAndView("/login/login");
			modelAndView.addObject("registedUser", new User());
			return modelAndView;
		}

		modelAndView = new ModelAndView("/admin/monthlyaspi/list");
		// SessionBean sBean = SessionBean.getInstance(request);
		LoadingSearchCriteria criteriaData = criteria;
		if (criteria == null) {
			criteriaData = new LoadingSearchCriteria();
		}
		// delete the selected criteria
		monthlyAspiDataService.deleteAspiData(criteriaData.getFromDate(),
				criteriaData.getToDate());

		// reload the page
		loadData(1, -1, criteriaData.getFromDate(), criteriaData.getToDate(),
				modelAndView, criteriaData);

		return modelAndView;
	}

}
